#pragma once
#include <compl.h>

#include <dinfra/list.h>
/* 线程本地的pslab，常用于在线程本地空间上开辟并且管理 */
/* 任意长度只申请不释放, 释放只释放obj_size */
typedef struct pslab{
	slist_t flist; /* 自由链表*/
	void   *bump_ptr;   /* 指向数据区的bump_ptr */
	size_t free_size; /* 包括数据结构的总长度 */
	size_t obj_size; /* slab大小 */
} pslab_t;


SAI void pslab_init(pslab_t *ps, void *ptr, size_t size, size_t obj_size){
	ps->bump_ptr = ptr;
	ps->free_size = size;
	ps->obj_size = obj_size;
	slist_init(&ps->flist);
}


SAI void *pslab_alloc(pslab_t *ps, size_t size){
	/* 如果flist为空 */
	void *ret = slist_pop(&ps->flist);
	if (!ret){
		size = align_up(size, ps->obj_size);
		if (size <= ps->free_size){
			ret = ps->bump_ptr;
			ps->free_size -= size;
			ps->bump_ptr = ps->bump_ptr + size;
		}
	}
	return ret;
}

SAI void pslab_free_batch(pslab_t *ps, slist_t *hd, slist_t *tl){
	slist_append(&ps->flist, hd, tl);
}

SAI void pslab_free(pslab_t *ps, slist_t *hd){
	pslab_free_batch(ps, hd, hd);
}